// src/api/index.ts
import request from '../utils/request';
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { ElMessage } from 'element-plus';
import { removeAllSession } from '../utils/session';
import {showLoading,hideLoading } from '@/utils/loading';
export const fetchData = () => {
    return request({
        url: './mock/table.json',
        method: 'get'
    });
};

export const fetchUserData = () => {
    return request({
        url: './mock/user.json',
        method: 'get'
    });
};

export const fetchRoleData = () => {
    return request({
        url: './mock/role.json',
        method: 'get'
    });
};

let urls = ["user/login"];


const setAuthorization = (url :string) :any=> {
   let loginKey = ""
   if( !urls.includes(url)){
        loginKey = sessionStorage.getItem('loginKey');
   }
   return loginKey;
};
/**
 * 封装请求方法
 */
export const ajax = async (options) => {
    const { url, method = 'GET', data = {}, success, error, loading = {open:true,text:"" }, aotuErrMsg = true } = options;
    if( loading.open ){
        showLoading(loading);
    }
    const headers = {
        Authorization:  setAuthorization(url),
        'Content-Type': 'application/json',
        'Custom-Header': 'CustomValue'
    };
    try {
        let response;
        if (method.toUpperCase() === 'GET') {
            response = await axios.get('/api/'+url, {
                headers: headers
            });
        } else if (method.toUpperCase() === 'POST') {
            response = await axios.post("/api/" + url, data, {
                headers: headers
            });
        } else {
            throw new Error(`Unsupported HTTP method: ${method}`);
        }

        if (success) {
            if( loading.open ){
                hideLoading();
            }
        
            success(response.data); // 传递响应数据
        }
    } catch (err) {
        if( loading.open ){
            hideLoading();
        }
        if (error) {
            error(err); // 传递错误对象
        } else {
            console.log('请求失败:', JSON.stringify(err.status));
            errorMsg(err.status);
        }
    }
};

/**
 * 文件上传
 * @param code 
 */
export const uploadFile = async (options) => {
    const { url, file, data = {}, success, error } = options; // 确保 data 默认值为一个空对象
    try {
        // 创建一个 FormData 对象
        const formData = new FormData();
        formData.append('file', file); // 假设后端接收文件的字段名为 'file'

        // 添加额外的表单数据
        if (data) {
            Object.keys(data).forEach(key => {
                formData.append(key, data[key]);
            });
        }

        // 发送 POST 请求
        const response = await axios.post(url, formData, {
            headers: {
                'Content-Type': 'multipart/form-data' // 确保使用 multipart/form-data
            }
        });

        // 调用成功回调（如果提供）
        if (success) {
            success(response.data);
        }
    } catch (err) {
        if (error) {
            error(err); // 传递错误对象
        } else {
            console.log('请求失败:', JSON.stringify(err.status));
            errorMsg(err.status);
        }
    }
};

/**
 * 文件下载
 * @param code 
 */
export const downloadFile = async (options) => {
    const { url, params = {}, fileName = 'downloaded-file', success, error } = options;
 
    try {
        // 发起 GET 请求，并设置 responseType 为 'blob'，以便接收二进制数据
        const response = await axios.get(url, {
            params, // 查询参数
            responseType: 'blob' // 指定响应类型为 Blob
        });
 
        // 创建一个 Blob 对象 URL
        const blob = new Blob([response.data]);
        const downloadUrl = window.URL.createObjectURL(blob);
 
        // 创建一个隐藏的 <a> 元素用于触发下载
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.download = fileName; // 指定下载的文件名
        document.body.appendChild(link); // 将 <a> 元素添加到 DOM 中
        link.click(); // 触发点击事件
        document.body.removeChild(link); // 下载完成后移除 <a> 元素
 
        // 释放 Blob 对象的 URL
        window.URL.revokeObjectURL(downloadUrl);
 
        // 调用成功回调（如果提供）
        if (success) {
            success(response.data); // 通常可以传递响应数据或元信息
        }
    } catch (err) {
        if (error) {
            error(err); // 传递错误对象
        } else {
            console.log('请求失败:', JSON.stringify(err.status));
            errorMsg(err.status);
        }
    }
};


/**
 *  base64图片上传
 * @param options 
 */
export const uploadImgBase64 = async (options) => {
    const { url,  base64, data = {}, success, error } = options; // 确保 data 默认值为一个空对象
    try {
        let formData = new FormData();
        const blob = base64ToBlob(base64);
        formData.append('file', blob); 
       
        // 添加额外的表单数据
        if (data) {
            Object.keys(data).forEach(key => {
                formData.append(key, data[key]);
            });
        }

        // 发送 POST 请求
        const response = await axios.post('/api/'+url, formData, {
            headers: {
                Authorization:  setAuthorization(url),
                'Content-Type': 'multipart/form-data' // 确保使用 multipart/form-data
            }
        });

        // 调用成功回调（如果提供）
        if (success) {
            success(response.data);
        }
    } catch (err) {
        if (error) {
            error(err); // 传递错误对象
        } else {
            console.log('请求失败:', JSON.stringify(err.status));
            errorMsg(err.status);
        }
    }
};
/**
 *  blob图片上传
 * @param options 
 */
export const uploadImgBlob = async (options) => {
    const { url,  file, data = {}, success, error, loading = {open:true,text:"" } } = options; // 确保 data 默认值为一个空对象
    try {
        if( loading.open ){
            showLoading(loading);
        }
        let formData = new FormData();
        formData.append('file', file); 
       
        // 添加额外的表单数据
        if (data) {
            Object.keys(data).forEach(key => {
                formData.append(key, data[key]);
            });
        }

        // 发送 POST 请求
        const response = await axios.post('/api/'+url, formData, {
            headers: {
                Authorization:  setAuthorization(url),
                'Content-Type': 'multipart/form-data' // 确保使用 multipart/form-data
            }
        });

        // 调用成功回调（如果提供）
        if (success) {
            if( loading.open ){
                hideLoading();
            }
            success(response.data);
        }
    } catch (err) {
        if( loading.open ){
            hideLoading();
        }
        if (error) {
            error(err); // 传递错误对象
        } else {
            console.log('请求失败:', JSON.stringify(err.status));
            errorMsg(err.status);
        }
    }
};

/**
 * 错误反馈处理
 * @param code 
 */
const errorMsg = (code: number) => {
    switch (code) {
        case 400:
            ElMessage.error('请求参数不正确，请核实！');
            break;
        case 401:
            ElMessage.error('登录状态已过期，请重新登录！');
            removeAllSession();
            break;
        case 403:
            ElMessage.error('当前用户无此操作权限！');
            break;
        case 404:
            ElMessage.error('请求地址错误！');
            break;
        case 500:
            ElMessage.error('服务器出现错误，请稍后再试！');
            break;
    }
}

/**
 * 将 Base64 字符串转换为 Blob 对象
 * @param base64String Base64 编码的字符串
 * @returns Blob 对象
 */
const base64ToBlob = (base64String: string): Blob => {
    // 提取 MIME 类型
    const parts = base64String.split(';base64,');
    const contentType = parts[0].split(':')[1];
    const raw = window.atob(parts[1]);
    const rawLength = raw.length;
    const uInt8Array = new Uint8Array(rawLength);

    for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }

    return new Blob([uInt8Array], { type: contentType });
};




